import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;

import edu.ucla.cs.typecast.net.NetUtil;


public class MulticastReceiver {
    public static void main(String[] args) { 
        byte[] buf = new byte[10240]; 
        int seqno = 0; 
        try {             
            Options options = new Options(args); 
            String group = options.getOption("-group"); 
            InetAddress grpAddr = InetAddress.getByName(group); 
            int port = Integer.parseInt(options.getOption("-port"));            
            String filter = options.getParameter(0); 
            BloomFilter bf = new BloomFilter(filter); 
            setLBF(grpAddr, bf);
            
            MulticastSocket socket = new MulticastSocket(port);             
            DatagramPacket packet = new DatagramPacket(buf, 0, buf.length); 
            socket.setBroadcast(true);
            socket.setNetworkInterface(NetworkInterface.getByName("eth1")); 
            socket.setLoopbackMode(false); 
            socket.setTimeToLive(16); 
            socket.joinGroup(grpAddr); 
            
            while(true) { 
                socket.receive(packet); 
                BloomFilter bloomFilter = new BloomFilter(buf, 0); 
                seqno = parseInteger(buf, BloomFilter.SIZE);
                System.out.println("Received packet from " + packet.getAddress() + " port " + packet.getPort() + " (seq=" + seqno + "), filter=" + bloomFilter.toString());            
            }
        } catch(Throwable t) { 
            t.printStackTrace(); 
        }

    }
    
    static int parseInteger(byte[] buf, int start) { 
        int value = (((int)buf[start] & 0xFF) << 24 )  | 
                    (((int)buf[start+1] & 0xFF) << 16) | 
                    (((int)buf[start+2] & 0xFF) << 8) | 
                    (buf[start+3] & 0xFF); 
        return value; 
    }
    
    private static void setLBF(InetAddress groupAddr, BloomFilter filter) { 
        try { 
        	byte buf[] = new byte[1024]; 
            DatagramSocket socket = new DatagramSocket(); 
            int index = 0; 
            buf[index++] = 1; // number of groups;
            
            System.arraycopy(groupAddr.getAddress(), 0, buf, index, 4);             
            index += 4; 
            /*
            byte[] addr = new byte[4]; 
            System.arraycopy(buf, 0, addr, 0, 4);
            InetAddress dst = InetAddress.getByAddress(addr); 
            System.out.println("group address = " + dst); 
            */
            System.arraycopy(filter.getValue(), 0, buf, index, BloomFilter.SIZE);             
            index += BloomFilter.SIZE; 
            DatagramPacket packet = new DatagramPacket(buf, 0, index, InetAddress.getByName("127.0.0.1"), 2004); 
            socket.send(packet); 
        } catch(Throwable t) { 
            t.printStackTrace(); 
        }
    }
}
